package main

import "fmt"

func main() {
	/*
		面向对象：OOP

		Go语言的结构体嵌套：
			1.模拟继承性：is -- a //类是一个特殊的父类
			（Go中没有“继承”的语义）
				type A struct {
					field
				}
				type B struct {
					A //匿名字段
				}
			如果一个struct嵌套了多个匿名结构体，那么它可以直接访问多个匿名结构体的方法，从而实现了多重继承

			2.模拟聚合关系（组合）：has -- a
				type C struct {
					field
				}
				type D struct {
					c C //聚合关系
				}
	*/
	//1.创建父类的对象
	p1 := Person0{name: "喜羊羊", age: 18}
	fmt.Println(p1)              //{张三 19}
	fmt.Println(p1.name, p1.age) //张三 19

	//2.创建子类的对象
	s1 := Student0{Person0{"灰太狼", 36}, "狼族教育学校"}
	fmt.Println(s1) //{{灰太狼 36} 狼族教育学校}

	s2 := Student0{Person0: Person0{name: "小灰灰", age: 7}, school: "大肥羊学校"}
	fmt.Println(s2) //{{小灰灰 7} 大肥羊学校}

	var s3 Student0
	s3.Person0.name = "孙悟空"
	s3.Person0.age = 5000
	s3.school = "花果山水帘洞"
	fmt.Println(s3) //{{孙悟空 5000} 花果山水帘洞}

	s3.name = "孙行者"
	s3.age = 5001
	fmt.Println(s3)

	fmt.Println(s1.name, s1.age, s1.school)
	fmt.Println(s2.name, s2.age, s2.school)
	fmt.Println(s3.name, s3.age, s3.school)
	/*
		s3.Person0.name ——> s3.name
		Student0 结构体将 Person0 结构体作为一个匿名字段了
		那么 Person0 中的字段，对于 Student0 来讲，就是提升字段
		Student0 对象就可以直接访问 Person0 中的字段了
	*/
}

// 1.定义父类
type Person0 struct {
	name string
	age  int
}

// 2.定义子类
type Student0 struct {
	Person0        //模拟继承
	school  string //子类的新增属性
}
